using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FrameworkDesign
{
    public class BindableProperty<T>
    {
        public BindableProperty()
        {

        }
        public BindableProperty(T def)
        {
            _value =def;
        }
        
        private T _value = default(T);

        public T mValue
        {
            get { return _value; }
            set
            {
               
                if (!object.Equals(_value, value))
                {
                    _value = value;
                    mOnValueChanged?.Invoke(_value);
                }
            }
        }
        private Action<T> mOnValueChanged = (v) => { }; 

        public IUnRegister RegisterOnValueChanged(Action<T> onValueChanged) 
        {
            mOnValueChanged += onValueChanged;
            return new BindablePropertyUnRegister<T>()
            {
                BindableProperty = this,
                OnValueChanged = onValueChanged
            };
        }
        public IUnRegister RegisterOnValueChangedInit(Action<T> onValueChanged)
        {
            mOnValueChanged += onValueChanged;
            mOnValueChanged.Invoke(_value);
            return new BindablePropertyUnRegister<T>()
            {
                BindableProperty = this,
                OnValueChanged = onValueChanged
            };
        }

        public void UnRegisterOnValueChanged(Action<T> onValueChanged) 
        {
            mOnValueChanged -= onValueChanged;
        }


    }

    public class BindablePropertyUnRegister<T> : IUnRegister 
    {
        public BindableProperty<T> BindableProperty { get; set; }

        public Action<T> OnValueChanged { get; set; }

        public void UnRegister()
        {
            BindableProperty.UnRegisterOnValueChanged(OnValueChanged);
        }
    }
    public class BindablePropertyGroup
    {
        private Action _onChanged;

        public void AddProperty<T>(BindableProperty<T> property)
        {
            property.RegisterOnValueChangedInit(_ => _onChanged?.Invoke());
        }

        public void SubscribeInit(Action onChanged)
        {
            _onChanged += onChanged;
            _onChanged.Invoke();
        }
    }
}




